package org.egedede.simulation.ui.desktop.swing;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Graphics;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JPanel;
import javax.swing.JToolBar;

import org.egedede.simulation.model.Simulation;

/**
 * Default implementation of simulation frame, There is no default view and one
 * default toolbar containing RunOnce Action RunUndefinitely Action Stop Action.
 */
public class SimulationFrame extends JFrame {

	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = -1318735521716746161L;

	/** The logger. */
//	private Logger logger = Logger.getLogger(SimulationFrame.class);

	/** toolbars list. */
	private Map<String, JToolBar> toolbars = new HashMap<String, JToolBar>();

	/** views list. */
	private Map<String, Set<SimulationView>> views = new HashMap<String, Set<SimulationView>>();

	/** The simulation. */
	private Simulation simulation;

	/** The container. */
	private ModelContainer container;

	/**
	 * Instantiates a new simulation frame.
	 */
	public SimulationFrame() {
		super();
		initGraphics();

	}

	/**
	 * Inits the.
	 */
	public void init() {
	}

	/**
	 * Inits the graphics.
	 */
	private void initGraphics() {
		JPanel contentPane = new JPanel(new BorderLayout());
		// First layer contains tool bars
		JPanel toolbarsPanel = new JPanel();
		toolbarsPanel.setLayout(new BorderLayout());
		contentPane.add(toolbarsPanel, BorderLayout.NORTH);

		if (simulation != null) {
			this
					.setTitle("Simulation of : "
							+ simulation.getModel().getLabel());
		}
		this.setContentPane(new JPanel(new BorderLayout()) {
			@Override
			public void paintComponent(Graphics g) {
				super.paintComponent(g);
				g.drawString("content pane", 0, 0);
			}
		});
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setSize(308, 365);
		this.setVisible(true);
	}

	/**
	 * Add an action to the specified tool bar. If the tool bar not defined then
	 * it's created
	 * 
	 * @param action
	 *            action to add to specified tool bar
	 * @param toolbarName
	 *            tool bar to add the action
	 */
	public void addAction(Action action, String toolbarName) {
		if (!this.toolbars.containsKey(toolbarName)) {
			JToolBar toolbar = new JToolBar();
			this.toolbars.put(toolbarName, toolbar);
			getContentPane().add(toolbar, BorderLayout.NORTH);
		}
		this.toolbars.get(toolbarName).add(action);
	}

	/**
	 * Add an action to the specified tool bar. If the tool bar not defined then
	 * it's created
	 * 
	 * @param action
	 *            action to add to specified tool bar
	 * @param toolbarName
	 *            tool bar to add the action
	 */
	public void addAction(Component action, String toolbarName) {
		if (!this.toolbars.containsKey(toolbarName)) {
			JToolBar toolbar = new JToolBar();
			this.toolbars.put(toolbarName, toolbar);
			getContentPane().add(toolbar, BorderLayout.NORTH);
		}
		this.toolbars.get(toolbarName).add(action);
	}

	/**
	 * Add a view to the specified location. If the location not defined then
	 * throws an exception
	 * 
	 * @param view
	 *            view to add to specified location
	 * @param location
	 *            to add the view
	 * 
	 * @return true if a model is associated with container
	 */
	public boolean addView(SimulationView view, String location) {
		if (!views.containsKey(location)) {
			views.put(location, new TreeSet<SimulationView>());
		}
		views.get(location).add(view);
		JInternalFrame internalFrame = new JInternalFrame();
		internalFrame.add(view);
		// add(internalFrame);
		getContentPane().add(view);
		internalFrame.setVisible(true);
		this.container.addObserver(view);
		return true;
	}


	/**
	 * Sets the actions.
	 * 
	 * @param actions
	 *            the new actions
	 */
	public void setActions(List actions) {
		Iterator iterator = actions.iterator();
		while (iterator.hasNext()) {
			Object action = iterator.next();
			addAction(action, "general");
		}
	}

	/**
	 * @param action
	 * @param string
	 */
	private void addAction(Object action, String string) {
		if(action instanceof Action){
			addAction((Action)action,string);
		}else if (action instanceof Component){
			addAction((Component)action,string);
		}
		
	}

	/**
	 * Sets the simulation view.
	 * 
	 * @param view
	 *            the new simulation view
	 */
	public void setSimulationView(SimulationView view) {
		this.addView(view, "test");
	}

	/**
	 * Sets the simulation.
	 * 
	 * @param view
	 *            the new simulation
	 */
	public void setSimulation(Simulation view) {
		this.simulation = view;
		this.setTitle(view.getModel().getLabel());
	}

	/**
	 * Setted by spring.
	 * 
	 * @param manager
	 *            the simulation manager
	 */
	public void setContainer(ModelContainer manager) {
		this.container = manager;
	}

}
